"""XML Database Functionality"""
import os

import paste.reloader as reloader
import pylons.config

from millhouse.exceptions import DBNotSupported
import millhouse.backends.marklogic as marklogic

supported_dbs = ['marklogic']

def get_dbinfo():
    conf = pylons.config._current_obj()
    session = conf['millhouse.session']
    dbtype = conf['millhouse.dbtype']
    dbname = conf['millhouse.dbname']
    return session, dbtype, dbname

def get_dbconfig():
    dbopts = {}
    dbopts['dbtype'], dbstring = pylons.config['millhouse.dburi'].split('://')
    dbstring, dbopts['dbname'] = dbstring.split('/')
    userpass, hostinfo = dbstring.split('@')
    dbopts['user'], dbopts['password'] = userpass.split(':')
    dbopts['host'], dbopts['port'] = hostinfo.split(':')
    dbopts['port'] = int(dbopts['port'])
    return dbopts

def init_db():
    """Initialize the XML Database Session object"""
    dbopts = get_dbconfig()
    
    if dbopts['dbtype'] not in supported_dbs:
        raise DBNotSupported("%s is not a supported XML database." % dboptsp['dbtype'])
    
    if dbopts['dbtype'] == 'marklogic':
        pylons.config['millhouse.session'] = marklogic.load_session(
            dbopts['user'], dbopts['password'], dbopts['host'], dbopts['port'])
    pylons.config['millhouse.dbtype'] = dbopts['dbtype']
    pylons.config['millhouse.dbname'] = dbopts['dbname']

def load_module(module, name=None):
    """Load a XQuery module into the XML Database"""
    if not name:
        name = os.path.basename(module)
    dbopts = get_dbconfig()
    
    if dbopts['dbtype'] == 'marklogic':
        session = marklogic.load_session(dbopts['user'], dbopts['password'], 
                                         dbopts['host'], dbopts['port'],
                                         dbname='Modules')
        marklogic.load_module(session, module, name)

def load_modules(xquery_directory, prefix=''):
    """Loads XQuery modules into the XML Database
    
    Given a directory of xquery modules, load all .xqy modules into the XML 
    Database, and register the filename with the Paste reloader to trigger
    automatic reloads of XQuery modules.
    """
    dbopts = get_dbconfig()
    
    if not prefix:
        prefix = '/' + dbopts['dbname']
    for name in os.listdir(xquery_directory):
        filename = os.path.sep.join([xquery_directory, name])
        if os.path.isdir(filename):
            load_modules(filename, prefix='/'.join([prefix, name]))
        elif filename.endswith('.xqy'):
            reloader.watch_file(filename)
            load_module(filename, name='/'.join([prefix, name]))

def adhoc_query(*args, **kwargs):
    session, dbtype, dbname = get_dbinfo()
    if dbtype == 'marklogic':
        return marklogic.adhoc_query(session, *args, **kwargs)

def invoke_module(*args, **kwargs):
    session, dbtype, dbname = get_dbinfo()
    if dbtype == 'marklogic':
        return marklogic.invoke_module(session, *args, **kwargs)

class XQuery(object):
    """Magic proxy module to shuttle commands to module invocation"""
    def __init__(self, path=''):
        self.path = path
    
    def __getattr__(self, name):
        return XQuery(path='/'.join([self.path, name]))
    
    def __call__(self, **kwargs):
        return invoke_module("%s.xqy" % self.path, **kwargs)

xq = XQuery()
